package com.bubblegumproject.ogo.action;

import com.bubblegumproject.ogo.component.ActionHandler;
import com.bubblegumproject.ogo.component.PostConstruct;
import com.bubblegumproject.ogo.component.PreDestroy;
import org.apache.log4j.Logger;

/**
 * A skeletal base implementation of the {@link Agent} interface. Subclasses need only know how to start and stop
 * {@link FlowExecution} instances and this class will take care of the rest.
 *
 * @author Azubuko Obele (buko.obele@gmail.com)
 */
public abstract class AbstractAgent extends AbstractFlow implements Agent {

    private static final Logger log = Logger.getLogger(AbstractAgent.class);

    /**
     * @return Always return <code>false</code>. Agents live for the lifetime of the system and do not terminate.
     */
    public boolean isFinished() {
        return false;
    }

    /**
     * Create the Context for this Agent by invoking {@link #createContext()}.
     */
    @PostConstruct
    public void start() {
        context = createContext();
    }

    @PreDestroy
    public void stop() {
        ; // do nothing
    }

    protected Context createContext() {
        Context context = new SimpleContext((parent != null ? parent.getContext() : null));
        ((SimpleContext) context).setName(getClass().getName());
        String prefix = getClass().getName();
        context.set(prefix + "flow", this);
        return context;
    }

    @ActionHandler
    public Action react(Action action) {
        assert (action != null);
        FlowExecution flowExecution = start(action);
        action.setFlow(flowExecution.getFlow());

        flowExecution.execute(action);

        stop(flowExecution);

        return action;
    }

    protected abstract FlowExecution start(Action action);

    protected abstract void stop(FlowExecution flowExecution);
}
